
package py.fpuna.ii.electiva2.client.clases;

import py.fpuna.ii.electiva2.client.model.ProductoModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import py.fpuna.ii.electiva2.client.GWTServiceProd;
import py.fpuna.ii.electiva2.client.GWTServiceProdAsync;
import py.fpuna.ii.electiva2.client.model.ProveedorModel;
/**
 *
 * @author gonzaleza
 */
public class ABMProductos extends VerticalPanel {

    ABMProductos miABM;

    FlexTable datos = new FlexTable();

    TextBox textDescripcion = new TextBox();
    TextBox textCantidad = new TextBox();
    ListBox listProv = new ListBox();
    TextBox textPrecioCompra = new TextBox();
    TextBox textPrecioVenta = new TextBox();
    TextBox textProv = new TextBox();

    Button guardar = new Button("Agregar");
    Button modificar = new Button("Modificar");


    private HorizontalPanel buscador = new HorizontalPanel();
    private Label buscarProductoDescripcion = new Label("Buscar por descripcion de Producto");
    private TextBox buscarProducto = new TextBox();
    private Button botonBuscar = new Button("Buscar");


    private Label resultado = new Label();
    public FlexTable tablaProd = new FlexTable();
    List <Integer> listCodeProv = new ArrayList<Integer>();

    Integer idProducto;  //identificador de la clave del producto usada en los metodos finales

    ProductoModel pM; //productoModel, para los metodos dentro del asynCallBack

    public ABMProductos(){
        
        datos.setText(0, 0, "Descripción");
        datos.setText(1, 0, "Cantidad");
        datos.setText(2, 0, "Proveedor");
        datos.setText(3, 0, "Precio de Compra");
        datos.setText(4, 0, "Precio de Venta");
        datos.setWidget(0,1, this.textDescripcion);
        datos.setWidget(1,1, this.textCantidad);
        datos.setWidget(2,1, this.listProv);
        datos.setWidget(3,1, this.textPrecioCompra);
        datos.setWidget(4,1, this.textPrecioVenta);

        miABM = this;   //me referencio a mi mismo
        miABM.add(datos);
        miABM.add(guardar);
        cargarListaProv();

        textProv.setEnabled(false);
        textProv.setVisible(false);
        modificar.setVisible(false);
        miABM.add(modificar);

        miABM.add(resultado);

        buscador.setSpacing(5);
        buscador.add(buscarProductoDescripcion);
        buscador.add(buscarProducto);
        buscador.add(botonBuscar);
        miABM.add(buscador);

        mostrarTabla(); //reconstruye la tabla

        guardar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                agregarProducto();
            }
        });

        botonBuscar.addClickHandler(new ClickHandler(){
            public void onClick(ClickEvent event) {
                buscarProductos(buscarProducto.getText());
            }
        });

    }

    public static GWTServiceProdAsync getService() {
        return GWT.create(GWTServiceProd.class);
    }


    private void agregarProducto()
    {
        String des = this.textDescripcion.getText();
        
        //retorna el indice del cod del proveedor seleccionado
        Integer index =  this.listProv.getSelectedIndex(); 
        Integer codProv = Integer.parseInt(listProv.getValue(index));

        String can = this.textCantidad.getText();
        String pComp = this.textPrecioCompra.getText();
        String pVent = this.textPrecioVenta.getText();


        if ( des.compareTo("") == 0 ||
             index == 0 || //no eligió proveedor
             can.compareTo("") == 0 ||
             pComp.compareTo("") == 0 ||
             pVent.compareTo("") == 0)
        {
            Window.setTitle("TAREA GWT - EJB");
            Window.alert("Debe cargar todos los campos");
            textDescripcion.setFocus(true);
            return;
        }

        ProductoModel product = new ProductoModel();
        product.setProdDescripcion(des);

        ProveedorModel proveedor = new ProveedorModel(codProv);
        product.setProdProveedor(proveedor);
        
        product.setProdCantidad(Integer.parseInt(can));
        product.setProdPrecioCompra(Integer.parseInt(pComp));
        product.setProdPrecioVenta(Integer.parseInt(pVent));


        // Crear una devolución de llamada asincrónica para manejar el resultado.
        final AsyncCallback<String> callback = new AsyncCallback<String>() {
            public void onSuccess(String result) {
                if (result.equalsIgnoreCase("true")){
                    textDescripcion.setText("");

                    listProv.clear(); //limpiamos todo y volvemos a cargar
                    cargarListaProv();

                    textCantidad.setText("");
                    textPrecioCompra.setText("");
                    textPrecioVenta.setText("");
                    idProducto = null;
                    Window.alert("Registro guardado satisfactoriamente");
                    mostrarTabla();
                }else{
                    Window.alert("Error. El registro no ha sido guardado");
                }
            }
            public void onFailure(Throwable caught) {
                Window.alert("Hey! Ingresá palabras mas cortas en los campos");
            }
        };

        getService().guardarProducto(product, callback);

    }


   private void buscarProductos(String nomProd){
        miABM.remove(tablaProd);
        tablaProd = new FlexTable();

        final AsyncCallback< List<ProductoModel> > callback2 = new AsyncCallback< List<ProductoModel> >() {

            public void onFailure(Throwable caught) {
                resultado.setText("he fallado");
            }

            public void onSuccess(List<ProductoModel> result) {
                if (result.isEmpty())
                    resultado.setText("no hay datos en tabla");
                else{

                    tablaProd.setWidth("800px");
                    tablaProd.setBorderWidth(1);
                    tablaProd.setText(0, 0, "DescripciÃ³n");
                    tablaProd.setText(0, 1, "Cantidad");
                    tablaProd.setText(0, 2, "Proveedor");
                    tablaProd.setText(0, 3, "Precio de Compra");
                    tablaProd.setText(0, 4, "Precio de Venta");
                    tablaProd.setText(0, 5, "Modificar");
                    tablaProd.setText(0, 6, "Eliminar");

                    int f=0;
                    for (ProductoModel prod : result){
                        f++;
                        tablaProd.setWidget(f, 0, new Label(prod.getProdDescripcion()));
                        tablaProd.setWidget(f, 1, new Label(prod.getProdCantidad().toString()));
                        tablaProd.setWidget(f, 2, new Label(prod.getProdProveedor().getProvRazonSocial()));
                        tablaProd.setWidget(f, 3, new Label(prod.getProdPrecioCompra().toString()));
                        tablaProd.setWidget(f, 4, new Label(prod.getProdPrecioVenta().toString()));

                        final Integer key = prod.getProdCodigo();
                        pM = prod; //prepara un producto para modificarlo

                        tablaProd.setWidget(f, 5, new Button("Modificar", new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            modificarProducto(key, pM);
                                                        }
                                                    }));
                        tablaProd.setWidget(f, 6, new Button("Eliminar",  new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            eliminarProducto(key);
                                                        }
                                                    }));

                    }

                }

                miABM.add(tablaProd); //cargo la tabla en mi mismo

            }

        };

        getService().listarProductosEncontrados(nomProd, callback2);

    }


    private void mostrarTabla(){
        miABM.remove(tablaProd);
        tablaProd = new FlexTable();
        
        final AsyncCallback< List<ProductoModel> > callback2 = new AsyncCallback< List<ProductoModel> >() {

            public void onFailure(Throwable caught) {
                resultado.setText("he fallado");
            }

            public void onSuccess(List<ProductoModel> result) {
                if (result.isEmpty())
                    resultado.setText("no hay datos en tabla");
                else{

                    tablaProd.setWidth("800px");
                    tablaProd.setBorderWidth(1);
                    tablaProd.setText(0, 0, "Descripción");
                    tablaProd.setText(0, 1, "Cantidad");
                    tablaProd.setText(0, 2, "Proveedor");
                    tablaProd.setText(0, 3, "Precio de Compra");
                    tablaProd.setText(0, 4, "Precio de Venta");
                    tablaProd.setText(0, 5, "Modificar");
                    tablaProd.setText(0, 6, "Eliminar");

                    Iterator <ProductoModel> prodIt = result.iterator();
                    
                    int f=1;
                    while (prodIt.hasNext()){
                        ProductoModel prod = prodIt.next();
                        tablaProd.setWidget(f, 0, new Label(prod.getProdDescripcion()));
                        tablaProd.setWidget(f, 1, new Label(prod.getProdCantidad().toString()));
                        tablaProd.setWidget(f, 2, new Label(prod.getProdProveedor().getProvRazonSocial()));
                        tablaProd.setWidget(f, 3, new Label(prod.getProdPrecioCompra().toString()));
                        tablaProd.setWidget(f, 4, new Label(prod.getProdPrecioVenta().toString()));

                        final Integer key = prod.getProdCodigo();
                        final ProductoModel pM = prod; //prepara un producto para modificarlo

                        tablaProd.setWidget(f, 5, new Button("Modificar", new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            modificarProducto(key, pM);
                                                        }
                                                    }));
                        tablaProd.setWidget(f, 6, new Button("Eliminar",  new ClickHandler() {
                                                        public void onClick(ClickEvent event) {
                                                            eliminarProducto(key);
                                                        }
                                                    }));

                        f++;
                    }

                }

                miABM.add(tablaProd); //cargo la tabla en mi mismo

            }

        };
   
        getService().listarProducto(callback2);
    }


    private void modificarProducto(Integer clave, ProductoModel prod){

        idProducto = clave; //identificador del producto

        pM = prod; //cargo el valor q recibo

        resultado.setText("codigo de producto "+pM.getProdProveedor().getProvCodigo());

        //le muestro lo que puede modificar
        this.textDescripcion.setText(prod.getProdDescripcion());
        this.textCantidad.setText(prod.getProdCantidad().toString());

        this.listProv.setItemText(0, prod.getProdProveedor().getProvRazonSocial());

        this.textPrecioCompra.setText(prod.getProdPrecioCompra().toString() );
        this.textPrecioVenta.setText(prod.getProdPrecioVenta().toString() );

        final AsyncCallback<String> callback4 = new AsyncCallback<String>() {
            public void onSuccess(String result) {
                if (result.equalsIgnoreCase("modificado")){

                    idProducto = null;   //ya no uso mas idProducto, entonces limpio
                    
                    modificar.setVisible(false);
                    guardar.setVisible(true);

                    //limpio todo lo que use
                    textDescripcion.setText("");
                    
                    listProv.clear();
                    cargarListaProv();

                    textCantidad.setText("");
                    textPrecioCompra.setText("");
                    textPrecioVenta.setText("");

                    Window.alert("Registro modificado satisfactoriamente");
                    mostrarTabla();

                }else{
                    Window.alert("Error. El registro no ha sido modificado");
                }
            }
            public void onFailure(Throwable caught) {
                Window.alert("Ingrese palabras mas cortas en los campos");
            }
        };

        //oculto el boton guardar y muestro el modificar
        guardar.setVisible(false);
        modificar.setVisible(true);

        //coloco la llamada remota en el boton modificar
        modificar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {

                //guardo lo que modifico
                String des = textDescripcion.getText();

                Integer index =  listProv.getSelectedIndex(); //nro del proveedor seleccionado
                Integer codProv = null;

                if(index == -1 || index == 0){ //si no selecciono nada
                    codProv = pM.getProdProveedor().getProvCodigo(); //conservamos el codigo original
                    pM=null;
                }else{
                    codProv = Integer.parseInt(listProv.getValue(index));
                }

                String can = textCantidad.getText();
                String pComp = textPrecioCompra.getText();
                String pVent = textPrecioVenta.getText();

                //verifico que todo este cargado
                 if ( des.compareTo("") == 0 ||
                     can.compareTo("") == 0 ||
                     pComp.compareTo("") == 0 ||
                     pVent.compareTo("") == 0) {

                    Window.setTitle("TAREA GWT - EJB");
                    Window.alert("Debe cargar todos los campos");
                    textDescripcion.setFocus(true);
                    return;
                }

                //actualizo los datos del producto guardandolos en uno nuevo
                ProductoModel productM = new ProductoModel();

                productM.setProdDescripcion(des);

                ProveedorModel proveedorM = new ProveedorModel(codProv);
                productM.setProdProveedor(proveedorM);

                productM.setProdCantidad(Integer.parseInt(can));
                productM.setProdPrecioCompra(Integer.parseInt(pComp));
                productM.setProdPrecioVenta(Integer.parseInt(pVent));

                //le paso el identificador del producto y lo que cambió
                getService().modificarProducto(idProducto, productM, callback4);
               }
        });
    }
    /**
     * elimina un prodc
     * @param codigo
     */
    private void eliminarProducto(Integer codigo){

        System.out.println(codigo);

        final AsyncCallback<String> callback3 = new AsyncCallback<String>() {
            public void onSuccess(String result) {
                Window.alert("Registro eliminado satisfactoriamente");
                mostrarTabla();
            }

            public void onFailure(Throwable caught) {
                Window.alert("Error no se puede eliminar un producto porque esta siendo utilizado");
            }
        };
        
        getService().eliminarProducto(codigo, callback3);
    }

    /**
     * carga la lista de proveedores que vemos en el listBox
     */
    private void cargarListaProv(){
        final AsyncCallback< List<ProveedorModel> > callback =new AsyncCallback< List<ProveedorModel> >() {

             public void onSuccess(List<ProveedorModel> result) {

                 Iterator<ProveedorModel> itProv = result.iterator();

                 listProv.addItem("<<seleccione un proveedor>>");
                 while (itProv.hasNext()){
                     ProveedorModel provm = itProv.next();
                     //item = razonSocial
                     //value = codigo.toString()
                     listProv.addItem(provm.getProvRazonSocial(), provm.getProvCodigo().toString());
                 }                 
            }

            public void onFailure(Throwable caught) {
                resultado.setText("Falló la comunicación");
            }

        };

        getService().listarProveedores(callback);
    }

}
